/**
 * @Title: ImgHelper.java
 * @Package com.hfi.common.util
 * @author YangChaofeng 2016年10月21日 下午2:27:19
 * @Description: TODO<一句话描述其作用>
 */
package com.mililoan.common.utils;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mililoan.common.exception.BusinessException;


/**
 * @ClassName: ImgHelper
 * @Description: 上传图片帮助
 * @author YangChaofeng 2016年10月21日 下午2:27:19
 */
public class ImgHelper {

	private static final Logger	LOGGER			= LoggerFactory.getLogger(ImgHelper.class);
	private static final String	BASE64_PNG		= "data:image/png;base64,";
	private static final String	BASE64_JPG		= "data:image/jpeg;base64,";
	private static final float	QUALITY			= 1f;
	private static final double	MAX_SIZE		= 1024;										// 单位kb

	public static final String	UPLOAD			= "upload";
	public static final String	RESULT			= "RESULT";
	public static final String	DESC			= "DESC";
	public static final String	SUCC			= "SUCC";
	public static final String	FAIL			= "FAIL";
	public static final String	OUT_MONTH		= "outMonth";
	public static final String	OUT_IMG_NAME	= "imgName";
	public static final String	IMG_TYPE		= "imgType";

	/**
	 * 
	 * @Title: GenerateImage
	 * @Description: base64字符串转化成图片,并上传
	 * @author YangChaofeng 2016年10月21日 下午3:41:50
	 * @param imgStr
	 * @return
	 */
	public static Map<String, String> GenerateImage(String path, String imgStr, String oldFileName) {
		Map<String, String> retMap = new HashMap<String, String>();
		retMap.put(RESULT, FAIL);
		if (StringUtils.isNotEmpty(imgStr)) {
			if (StringUtils.startsWith(imgStr, BASE64_PNG)) {
				imgStr = imgStr.substring(BASE64_PNG.length(), imgStr.length());
			}
			if (StringUtils.startsWith(imgStr, BASE64_JPG)) {
				imgStr = imgStr.substring(BASE64_JPG.length(), imgStr.length());
			}
			Base64 decoder = new Base64();
			// 文件名后缀
			String postFix = getPostfix(oldFileName);
			try {
				// Base64解码
				@SuppressWarnings("static-access")
				byte[] b = decoder.decodeBase64(new String(imgStr).getBytes());
				for (int i = 0; i < b.length; ++i) {
					if (b[i] < 0) {
						b[i] += 256;
					}
				}
				Date now = new Date();
				// 原图路径
				String newImaPath = path + File.separator + new SimpleDateFormat("yyyyMM").format(now);
				String imgFilePath = newImaPath + File.separator + String.valueOf(now.getTime()) + "_so." + postFix;

				File newFile = new File(newImaPath);
				if (!newFile.exists()) {
					newFile.mkdirs();
				}

				OutputStream out = new FileOutputStream(imgFilePath);
				out.write(b);
				out.flush();
				out.close();

				retMap.put(OUT_MONTH, new SimpleDateFormat("yyyyMM").format(now));
				retMap.put(OUT_IMG_NAME, String.valueOf(now.getTime()));
				retMap.put(IMG_TYPE, postFix);
				retMap.put(RESULT, SUCC);
			} catch (Exception e) {
				System.out.println(e.getCause());
				LOGGER.error("图片处理异常：" + e.getMessage());
				retMap.put(RESULT, FAIL);
				retMap.put(DESC, "图片处理异常：" + e.getMessage());
			}
		} else {
			retMap.put(RESULT, FAIL);
			retMap.put(DESC, "缺失参数");
		}
		return retMap;
	}

	/**
	 * 
	 * @Title: zipWidthHeightImageFile
	 * @Description: 等比例压缩
	 * @author YangChaofeng 2016年10月24日 上午10:51:16
	 * @param inImg
	 * @param outImg
	 * @param thumbWidth
	 * @param thumbHeight
	 * @param quality
	 * @return
	 * @throws BusinessException
	 */
	public static Boolean zipWidthHeightImageFile(String inImg, String outImg, int thumbWidth, int thumbHeight,
			float quality) throws BusinessException {
		Boolean sta = false;
		File inFile = new File(inImg);
		File outFile = new File(outImg);
		try {

			quality = (quality == 0) ? QUALITY : quality;

			Image srcFile = ImageIO.read(inFile);
			int imageWidth = srcFile.getWidth(null); // 原图片宽
			int imageHeight = srcFile.getHeight(null); // 原图片长
			double imageSize = inFile.length() / 1024.0;
			if (imageSize < MAX_SIZE) { // 比1M小，则无需压缩
				quality = 1f;
			}
			if (thumbWidth > 0 && thumbHeight > 0) {
				double thumbRatio = (double) thumbWidth / (double) thumbHeight;
				double imageRatio = (double) imageWidth / (double) imageHeight;

				if (thumbRatio < imageRatio) {
					thumbHeight = (int) Math.round(thumbWidth / imageRatio);
				} else {
					thumbWidth = (int) Math.round(thumbHeight * imageRatio);
				}
			} else {
				thumbHeight = imageHeight;
				thumbWidth = imageWidth;
			}
			srcFile = srcFile.getScaledInstance(thumbWidth, thumbHeight, Image.SCALE_AREA_AVERAGING);

			BufferedImage mBufferedImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB);
			Graphics2D g = mBufferedImage.createGraphics();
			g.drawImage(srcFile, 0, 0, thumbWidth, thumbHeight, Color.white, null);
			g.dispose();

			String fileExtension = getPostfix(outImg);
			// float[] kernelData2 = { -0.125f, -0.125f, -0.125f, -0.125f, 2,
			// -0.125f, -0.125f, -0.125f, -0.125f };
			// Kernel kernel = new Kernel(3, 3, kernelData2);
			// ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,
			// null);
			// mBufferedImage = cOp.filter(mBufferedImage, null);
			if (fileExtension.equalsIgnoreCase("jpg") || fileExtension.equalsIgnoreCase("jpeg")
					|| fileExtension.equalsIgnoreCase("bmp")) {
				mBufferedImage = copy(mBufferedImage, BufferedImage.TYPE_INT_RGB);
			}
			ImageWriter imgWriter = ImageIO.getImageWritersByFormatName(fileExtension).next();
			ImageWriteParam imgWriteParam = imgWriter.getDefaultWriteParam();
			if (imgWriteParam.canWriteCompressed()) {
				imgWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
				imgWriteParam.setCompressionQuality(quality);
			}
			ImageOutputStream outputStream = ImageIO.createImageOutputStream(outFile);
			imgWriter.setOutput(outputStream);
			IIOImage outputImage = new IIOImage(mBufferedImage, null, null);
			imgWriter.write(null, outputImage, imgWriteParam);
			imgWriter.dispose();
			outputStream.close();

			sta = true;
			LOGGER.info("图片压缩成功，文件路径为：" + outImg);
		} catch (Exception e) {
			LOGGER.error("压缩图片失败");
			LOGGER.error(StackTraceUtil.getStackTrace(e));
			throw new BusinessException("-104", "压缩原图片失败");
		}
		return sta;
	}

	private static BufferedImage copy(BufferedImage img, int imageType) {
		int width = img.getWidth();
		int height = img.getHeight();

		BufferedImage newImage = new BufferedImage(width, height, imageType);
		Graphics g = newImage.createGraphics();
		g.drawImage(img, 0, 0, null);
		g.dispose();
		return newImage;
	}

	/**
	 * 
	 * @Title: getPostfix
	 * @Description: 得到文件后缀,默认为jpg
	 * @author YangChaofeng 2016年10月24日 上午10:29:39
	 * @param fileName
	 * @return
	 */
	public static String getPostfix(String fileName) {
		if (StringUtils.isEmpty(fileName))
			return "jpg";
		int pos = fileName.lastIndexOf(".");
		if (pos < 0) {
			// return fileName.substring(fileName.length() - 3).toLowerCase();
			return "jpg";
		} else {
			return fileName.substring(pos + 1).toLowerCase();
		}
	}

	/**
	 * 
	 * @Title: deleteFileSource
	 * @Description: 删除服务器资源文件
	 * @author YangChaofeng 2016年10月26日 上午9:47:13
	 * @param filePath
	 * @return
	 */
	public static Boolean deleteFileSource(String filePath) {
		Boolean ret = true;
		File file = new File(filePath);
		if (file.exists() && file.isFile()) {
			if (file.delete()) {
				ret = true;
			} else {
				ret = false;
			}
		}
		return ret;
	}
}
